//---------------------------- //Utility defines (define "PlayableSite" (difference (sites Occupied by:Mover))) (define "ValueAtTo" (max 1 (max (results from:(last To) to:("FirstFriend" Orthogonal) (size Group at:(to) Orthogonal if:(= (mover) (who at:(to)))) ) ) ) ) (define "ValueAtFrom" (set Var "MaxSizeFrom" (max 1 (max (results from:(from) to:("FirstFriend" Orthogonal) (size Group at:(to) Orthogonal if:(= (mover) (who at:(to)))) ) ) ) ) ) (define "FirstFriend" (sites To (move Hop #1 (between (min 0) if:(or { (= (from) (between)) (is Next (who at:(between))) (is Empty (between)) } ) ) (to if:(is Mover (who at:(to)))) ) ) ) //-------------------------------------------------------- // Variants (define "Astralesce" (forEach Piece (do ("ValueAtFrom") next:(do (move Slide Orthogonal (between if:(or (= (between) (from)) (is In (between) "PlayableSite")) (apply (remove (between))) ) (to ("PlayableSite")) ) ifAfterwards:(> "ValueAtTo" (var "MaxSizeFrom")) ) ) ) ) (define "Constellate" (forEach Piece (do ("ValueAtFrom") next:(do (move Slide Orthogonal (between if:(or (= (between) (from)) (is In (between) (intersection (sites Empty))) ) ) (to if:(is Next (who at:(to))) (apply (remove (to))) ) ) ifAfterwards:(> "ValueAtTo" (var "MaxSizeFrom")) ) ) ) ) //----------------------------------------------- // Main routine (game "Astralesce and Constellation" (players 2) (equipment { (board (hex Hexagon ) use:Cell) (piece "Disc" Each) }) (rules (start { }) (play ) (end ) ) ) //-------------------------------------- // End conditions (define "IsSingleGroupOf" (= 1 (count Groups Cell Orthogonal if:(is #1 (who at:(to))) ) ) ) (define "StandardEnd" (if (or { (no Moves Next) ("IsSingleGroupOf" Mover) ("IsSingleGroupOf" Next) }) { (if ("IsSingleGroupOf" Mover) (result Mover Win) ) (if ("IsSingleGroupOf" Next) (result Next Win) ) ("AMSEnd") } )) (define "AMSEnd" (if (no Moves Next) (result Mover Loss))) (define "Last2MoveEnd" ("BlockWin")) (define "Dummy" (place 1)) //------------------------------------------------- // Options (option "Game" args:{ } { (item "Astralesce" <"Astralesce"> <"StandardEnd"> <"Starfour"> // <"Disc"> "Astralesce: Capturing every opponent's piece along the way, slide a piece to a location in-line with larger groups than the piece had been in-line with before moving. (A group is considered in-line if it contains the first friendly piece along any of the 6 radial grid directions.) Win when unified; if tied, the mover wins." ) (item "Constellate" <"Constellate"> <"StandardEnd"> // <"AMSEnd"> <"Starfour"> "Constellate: Slide a piece to a location in-line with larger groups than the piece had been in-line with before moving. (A group is considered in-line if it contains the first friendly piece along any of the 6 radial grid directions.) An opponent's piece at the destination is removed. Win when unified; if tied, the mover wins. However, a player who prevents his opponent from moving before either has won, loses." ) } ) (option "Board Size" args:{ } { (item "Order 3" <4> <(sites Inner)> // <(place "Disc1" {5 12 17 20 25 29 })> // <(place "Disc2" {7 11 16 19 24 31 })> <(place "Disc1" {2 5 8 9 12 17 20 25 29 })> <(place "Disc2" {1 4 7 11 14 16 19 24 31 })> "Order 4 board") (item "Order 4" <5> <(sites Inner)> <(place "Disc1" {7 12 15 21 24 28 31 38 41 44 47 52})> <(place "Disc2" {8 13 16 19 22 29 32 36 39 45 48 53})> "Order 4 board")* (item "Order 5" <5> <(sites Board)> <(place "Disc1" {0 3 7 10 12 15 18 21 24 28 31 34 35 38 41 44 47 52 55 56 59})> <(place "Disc2" {1 4 5 8 13 16 19 22 25 26 29 32 36 39 42 45 48 50 53 57 60})> "Order 5 board") (item "Order 6" <6> <(sites Board)> <(place "Disc1" {0 3 8 11 14 17 20 21 24 27 32 35 38 41 44 47 50 53 56 59 61 64 67 71 74 77 80 83 85 88})> <(place "Disc2" {2 5 7 10 13 16 19 23 26 29 31 34 37 40 43 46 49 52 55 58 63 66 69 70 73 76 79 82 87 90})> "Order 6 board") } ) //--------------------------------------------- (define "ColourBackground" (colour 245 245 245)) (metadata (info { (description "'Astralesce' and 'Constellate' are games based loosely on Kanare Kato's 'Advanced Squish'. The mechanism found in 'advanced Squish' of: 'move toward in-line-targets that are part of larger groups', is extended in these games to a future look-ahead restriction, i.e.: 'move along a line from a starting location to a location that is in line with a larger group than the moving piece had been in line with before.' This is inherently difficult perceptually, and it remains to be seen if the game can be played without the assistance of an app. However, the game is both interesting and exciting, and appears to have various levels of strategy. The goal is unification, and causing a stalemate before achieving the goal is considered a loss. 'Astralesce' has sliding moves and captures that can remove multiple pieces. Thus, stalemate is impossible, as the opponent cannot block movement. This is the preferred game. 'Constellation' also has sliding moves, but only allows capture at the move's designation. This means opponent's pieces can block some potential destinations.") (rules "Setup: Pieces of each color are distributed symmetrically on every 3rd cell of the board. Play - Decide which player will play with which color (Dark or Light). - Light is the first player to play. - Players take turns moving one of their own pieces - Passing is not allowed. Ending the game: The game ends when one player's pieces all form a single group. That player wins. If tied, the moving player wins. Note: The Game 'Constellation' can also end in Stalemate if a player cannot move. In this case the last to move loses. How to make a move: 1) Choose a piece to play. 2) Note the size of the first friendly group in each direction. (If the piece is not a singleton, one of these is the group the piece is part.) 3) The largest of these gives the starting value for the move. 4) Try to move the chosen piece in any of the six radial directions. -- (In Astralesce, as the piece moves it will capture every opponent's piece that it reaches.) 5) For the piece to be able to move, it must stop on a destination at which it has a higher value than before. -- The ending value is found in the same way as the starting value was found: It is the size of largest of the nearest friendly groups on a radial line from the new location. Notes on what to look for to find moves quickly: A) move to join the largest group in-line with the piece. B) If the piece is already in the largest in-line group, then move to connect that group to another. C) move to join a non-in-line group that is at least as big as the largest in-line group D) move to connect 2 groups to make the result larger than the largest in-line group E) find the all the lines radiating from all pieces of all groups that are larger than the largest in-line group, and move to a location on one of those lines.") (id "1731") (version "1.3.12") (classification "experimental") (author "Dale W. Walton") (credit "Dale W. Walton") (date "14-10-2021") } ) (graphics { (player Colour P1 (colour White)) (player Colour P2 (colour Black)) (piece Scale "Disc" 0.91) (piece Colour P1 strokeColour:(colour VeryDarkGrey)) (piece Colour P2 strokeColour:(colour DarkGrey)) (piece Background "Disc" image:"Disc" fillColour:(colour 0 0 0 75) edgeColour:(colour 0 0 0 0) scale:0.95 offsetX:-1 offsetY:2) (piece Foreground "Disc1" image: scale:0.75) // fillColour:(colour 0 0 0 75) edgeColour:(colour 0 0 0 0) scale:0.70 (piece Foreground "Disc2" image: fillColour:(colour 255 255 255 60) edgeColour:(colour 255 255 255 120) scale:0.70) (board Colour Phase0 (colour 220 230 245)) (board StyleThickness InnerEdges 1.6) (board StyleThickness OuterEdges 1.6) (board StyleThickness InnerVertices 0.45) (board StyleThickness OuterVertices 0.45) (board Colour InnerVertices (colour Grey)) (board Colour OuterVertices (colour Grey)) (board Colour InnerEdges (colour Black)) (board Colour OuterEdges (colour Black)) (region Colour (sites Outer) (colour 180 192 210)) } ) (ai "Astralesce and Constellation_ai" ) )